#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <arpa/inet.h>

#include "message.h"

void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


int main(int argc, char *argv[])
{
	int sockfd, numbytes;  
	char buf[1000];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];

	if (argc != 2) {
		fprintf(stderr,"usage: client hostname\n");
		exit(1);
	}

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if ((rv = getaddrinfo(argv[1], "179", &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}

	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
			p->ai_protocol)) == -1) {
		    perror("client: socket");
		    continue;
	}

	if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
    	    close(sockfd);
	    perror("client: connect");
	    continue;
	}

	break;
	}

	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}

	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
	printf("client: connecting to %s\n", s);

	freeaddrinfo(servinfo); // all done with this structure

	//if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
	//	perror("recv");
	//	exit(1);
	//}

	//buf[numbytes] = '\0';

	//printf("client: received '%s'\n",buf);

	using namespace sobriety;
	struct bgp_settings settings;
	settings.version = 4;
	settings.as = 65001;
	settings.hold = 60;
	settings.id = 4294967295;
		
	
	void *data;
	int length;

	Message test1(kKeepalive, &settings);
	data = test1.getData();
	length = test1.getLength();
	send(sockfd, data, length, NULL);
	Message test2(kOpen, &settings);
	data = test2.getData();
	length = test2.getLength();
	send(sockfd, data, length, NULL);
	Message test3(kNotification, &settings);
	data = test3.getData();
	length = test3.getLength();
	send(sockfd, data, length, NULL);


	//send(sockfd, data, length, NULL);

	close(sockfd);	

	return 0;
}
